﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using rossisdead.Mvc.Detergent;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace MMSINC.CoreTest.DesignPatterns.Mvc.Metadata
{
    [TestClass]
    public class CascadingAttributeTest
    {
        #region Fields

        private CascadingAttribute _target;
        private ModelMetadataProvider _originalProvider;

        #endregion

        #region Init
        
        [TestInitialize]
        public void InitializeTest()
        {
            _originalProvider = ModelMetadataProviders.Current;
            ModelMetadataProviders.Current = new CustomModelMetadataProvider();
            _target = new CascadingAttribute();
        }

        [TestCleanup]
        public void CleanupTest()
        {
            ModelMetadataProviders.Current = _originalProvider;
        }

        #endregion

        #region Tests

        #region Properties

        [TestMethod]
        public void TestActionGetsAndSets()
        {
            _target.Action = "Heyo";
            Assert.AreEqual("Heyo", _target.Action);
        }

        [TestMethod]
        public void TestDependsOnGetsAndSets()
        {
            _target.DependsOn = "Some dependable thing";
            Assert.AreEqual("Some dependable thing", _target.DependsOn);
        }

        [TestMethod]
        public void TestErrorTextGetsAndSets()
        {
            _target.ErrorText = "Errory";
            Assert.AreEqual("Errory", _target.ErrorText);
        }

        [TestMethod]
        public void TestHttpMethodGetsAndSets()
        {
            _target.HttpMethod = "Methody";
            Assert.AreEqual("Methody", _target.HttpMethod);
        }


        [TestMethod]
        public void TestLoadingTextGetsAndSets()
        {
            _target.LoadingText = "Loadingy";
            Assert.AreEqual("Loadingy", _target.LoadingText);
        }

        [TestMethod]
        public void TestPromptTextGetsAndSets()
        {
            _target.PromptText = "Prompty";
            Assert.AreEqual("Prompty", _target.PromptText);
        }

        #endregion

        #region OnMetadataCreated

        [TestMethod]
        public void TestOnMetadataCreatedThrowsIfActionIsNull()
        {
            // Setting DependsOn, because if it's null this will still throw an exception.
            _target.DependsOn = "efaaeae";
            Assert.IsNull(_target.Action);
            DetergentTest.TestHelper.Throws<ArgumentNullException>(() => _target.Process(null));
        }

        [TestMethod]
        public void TestOnMetadataCreatedThrowsIfDependsOnIsNull()
        {
            // Setting Action, because if it's null this will still throw an exception.
            _target.Action = "faefae";
            Assert.IsNull(_target.DependsOn);

            DetergentTest.TestHelper.Throws<ArgumentNullException>(() => _target.Process(null));
        }

      

        #endregion

        #region GetAttributeForModel

        [TestMethod]
        public void TestGetAttributeForModelReturnsSameInstanceAddedDuringProcess()
        {
            var md = ModelMetadataProviders.Current.GetMetadataForProperty(null, typeof(ViewModel), "CascadingProperty");
            _target.Action = "Action";
            _target.DependsOn = "ParentProperty";
            _target.Process(md);
            Assert.AreSame(_target, CascadingAttribute.GetAttributeForModel(md));
        }
        

        #endregion

        #endregion

        #region Helper classes
        
        private class ViewModel
        {
            public object ParentProperty { get; set; }
            public object CascadingProperty { get; set; }
        }

        #endregion

    }
}
